package xintegral

import (
	"fmt"
	"time"

	"gitee.com/xiaoyutab/xgotool/optional/xnsq"
	"gitee.com/xiaoyutab/xgotool/xerror"
	"gitee.com/xiaoyutab/xgotool/xstring"
)

// 创建积分变动信息
//
//	id		积分账户ID
//	bal		变动金额
//	desc	变动描述
//	call	是否回写主账户
func CreateHistory(id uint, bal int, desc string, call bool) error {
	return CreateHistoryTime(id, bal, desc, call, 0)
}

// 创建积分变动信息
//
//	id		积分账户ID
//	bal		变动金额
//	desc	变动描述
//	call	是否回写主账户
//	endT	结束时间【time.xxx * xxx的形式，此处使用 time.Now().Add().Format()进行存储】
//	endT参数描述：
//	0		表示参照默认
//	-1		表示永久有效(默认有效期到2099-12-31年)
//	1~11	表示往后x月有效(含11)
//	12~20	表示往后x-11年有效(含20)
func CreateHistoryTime(id uint, bal int, desc string, call bool, endT time.Duration) error {
	if id <= 0 {
		return xerror.New("积分ID不能为空")
	}
	if _default.DB == nil {
		return xerror.New("数据库未连接")
	}
	// 获取积分详情
	inf, err := Info(id)
	if err != nil {
		return err
	}
	mod := IntegralHistory{
		IntegralId: id,
		Balance:    bal,
		Desc:       desc,
		CreatedAt:  time.Now().Format(time.DateTime),
	}
	if mod.Balance < 0 {
		// 如果是扣除的话
		if mod.Balance+int(inf.Balance) < 0 {
			return xerror.New("账户余额不足以抵扣")
		}
	}
	if bal > 0 {
		mod.EndBalance = uint(bal)
	}
	if endT == 0 {
		if inf.Type == 1 {
			mod.EndDate = time.Now().AddDate(0, 0, int(inf.ExpireDays)).Format(time.DateOnly)
		} else if inf.Type == 2 {
			mod.EndDate = inf.EndDate
		} else if inf.Type == 3 {
			// 无期限设置
			mod.EndDate = "2099-12-31"
		} else if inf.Type == 4 {
			mod.EndDate = fmt.Sprintf("%d-%d-%d",
				time.Now().AddDate(int(inf.ExpireDays), 0, 0).Year(), // 年
				xstring.ToTime(inf.EndDate).Month(),                  // 月
				xstring.ToTime(inf.EndDate).Day(),                    // 日
			)
		}
	} else if endT == -1 {
		mod.EndDate = "2099-12-31"
	} else if endT >= 1 && endT < 12 {
		mod.EndDate = time.Now().AddDate(0, int(endT), 0).Format(time.DateOnly)
	} else if endT >= 12 && endT < 21 {
		mod.EndDate = time.Now().AddDate(int(endT)-11, 0, 0).Format(time.DateOnly)
	} else {
		mod.EndDate = time.Now().Add(endT).Format(time.DateOnly)
	}
	err = _default.DB.Save(&mod).Error
	if err != nil {
		return err
	}
	// 进行积分扣除
	if call {
		if mod.Balance > 0 {
			inf.Balance += uint(mod.Balance)
		} else {
			inf.Balance -= uint(0 - mod.Balance)
		}
		if inf.ExpireBalance > 0 {
			// 如果即将到期的余额里面也有值的话，此值也需要进行扣除
			if mod.Balance+int(inf.ExpireBalance) > 0 {
				inf.ExpireBalance = uint(mod.Balance + int(inf.ExpireBalance))
			} else {
				inf.ExpireBalance = 0
			}
		}
		// 写入主账户信息
		CreateIntegral(inf)
	}
	if inf.Type != 3 {
		for {
			// 扣除积分：bal
			// 每次查询条数：10
			if bal >= 0 {
				break
			}
			// 子条目账户扣除
			mods := []IntegralHistory{}
			_default.DB.Table(_default.IntegralHistoryName).
				Where("integral_id", id).
				Where("end_balance > 0").
				Where("end_date >= NOW()").
				Order("end_date ASC,created_at ASC").
				Limit(10).
				Find(&mods)
			if len(mods) <= 0 {
				break
			}
			for i := 0; i < len(mods); i++ {
				if bal+int(mods[i].EndBalance) <= 0 {
					// 如果不足以抵扣的话，则直接回写入数据库并从bal中进行扣除
					mods[i].EndBalance = 0
					// 写会数据库
					_default.DB.Save(&mods[i])
					bal += int(mods[i].EndBalance)
				} else if bal+int(mods[i].EndBalance) > 0 {
					if bal >= 0 {
						break
					}
					bal += int(mods[i].EndBalance)
					mods[i].EndBalance = uint(bal)
					// 写会数据库
					_default.DB.Save(&mods[i])
					break
				}
			}
		}
	}
	// 回调通知
	xnsq.Set(_default.HookIntegralHistoryEdit, mod)
	return nil
}
